home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 3 code / ISO 9660 & High Sierra / iso9660 ƒ / TextDlog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-16  |  9.3 KB  |  373 lines  |  [TEXT/KAHL]

  1. /*
  2.     Present a dialog box with a text rectangle, a scroll bar, and an OK
  3.     button.  This can be used as a help dialog.  Pass in a dialog
  4.     resource number and a handle to the text.  The dialog should
  5.     have the OK button as the first item, and user items for the
  6.     second and third items.  The second is the rect in which the
  7.     control is drawn, the third is the rect in which text is drawn.
  8.     Only the OK button should be enabled.
  9.  
  10.     The text handle should be locked before calling TextDlog and
  11.     unlocked after.
  12.  
  13.     Original author:                     dubois@uwmacc.UUCP (Paul DuBois)
  14.     with a few changes & cleanup by:     blob@apple.com    (Brian Bechtel)
  15. */
  16.  
  17. # include    <EventMgr.h>
  18. # include    <DialogMgr.h>
  19. # include    <ControlMgr.h>
  20. #include <stdio.h>
  21.  
  22. #include "textdlog.h"
  23. #include "DialogUtils.h"
  24.  
  25. # define    nil        0L
  26.  
  27. #define    ETX    03        /* Enter key */
  28. #define CR    13        /* Return key */
  29.  
  30. enum        /* item numbers */
  31. {
  32.     OKButton = 1,
  33.     scrollBarUser,
  34.     textRectUser
  35. };
  36.  
  37. static ControlHandle    theScroll;
  38. static Boolean            needScroll;    /* true if need scroll bar */
  39. static int                curLine;
  40. static int                halfPage;
  41. static TEHandle            teHand;
  42.  
  43.  
  44.  
  45. /************************************************************************
  46.  *
  47.  *  Function:        HighLightDefault
  48.  *
  49.  *  Purpose:        highlight the default button in a dialog
  50.  *
  51.  *  Returns:        nothing
  52.  *
  53.  *  Side Effects:    standard box is drawn around highlight box
  54.  *
  55.  *  Description:    draws the heavy rounded box around the OK button,
  56.  *                    so that the user knows that hitting enter or return
  57.  *                    is the same as pressing the OK button.
  58.  *
  59.  ************************************************************************/
  60. void
  61. HighLightDefault(dPtr)
  62. DialogPtr dPtr;
  63. {
  64.     int unusedItemType;
  65.     Handle unusedItemHandle;
  66.     Rect box;
  67.     PenState p;
  68.     GrafPtr    savedPort;
  69.  
  70.     /*    This next little piece of code puts the default heavy rounded
  71.         box around the "OK" button, so the user knows that pressing
  72.         return is the same as hitting "OK"
  73.     */
  74.     GetPort(&savedPort);
  75.     SetPort(dPtr);        /* without this, can't highlite OK */
  76.     GetDItem(dPtr, OKButton, &unusedItemType, &unusedItemHandle, &box);
  77.     GetPenState(&p);
  78.     PenSize(3,3);
  79.     InsetRect(&box, -4, -4);
  80.     FrameRoundRect(&box, 16, 16);
  81.     PenSize(p.pnSize.h, p.pnSize.v);
  82.     SetPort(savedPort);
  83. }
  84.  
  85. /************************************************************************
  86.  *
  87.  *  Function:        DrawScroll
  88.  *
  89.  *  Purpose:        draw scroll bar user item
  90.  *
  91.  *  Returns:        nothing
  92.  *
  93.  *  Side Effects:    draws scroll bar user item
  94.  *
  95.  *  Description:    if we need to scroll, show the control.
  96.  *
  97.  ************************************************************************/
  98. static pascal void DrawScroll (theDialog, itemNo)
  99. DialogPtr    theDialog;
  100. int            itemNo;
  101. {
  102.     if (needScroll)
  103.         ShowControl (theScroll);
  104. }
  105.  
  106.  
  107. /************************************************************************
  108.  *
  109.  *  Function:        DrawTextRect
  110.  *
  111.  *  Purpose:        draw text display user item
  112.  *
  113.  *  Returns:        nothing
  114.  *
  115.  *  Side Effects:    shows the text
  116.  *
  117.  *  Description:    Get the rectangle for our text.  If we need to scroll,
  118.  *                    frame the rectangle so that it will look correct.
  119.  *                    Get the view rectangle of our text rectangle, and do
  120.  *                    a TEUpdate so that text edit will properly handle
  121.  *                    updating the rectangle.
  122.  *
  123.  ************************************************************************/
  124. static pascal void DrawTextRect (theDialog, itemNo)
  125. DialogPtr    theDialog;
  126. int            itemNo;
  127. {
  128. Rect    r;
  129. int        itemType;
  130. Handle    itemHandle;
  131.  
  132.     GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
  133.     if (needScroll)
  134.         FrameRect (&r);
  135.     r = (**teHand).viewRect;
  136.     TEUpdate (&r, teHand);
  137. }
  138.  
  139.  
  140. /************************************************************************
  141.  *
  142.  *  Function:        DoScroll
  143.  *
  144.  *  Purpose:        scroll to correct position
  145.  *
  146.  *  Returns:        nothing.
  147.  *
  148.  *  Side Effects:    text is scrolled to new position
  149.  *
  150.  *  Description:
  151.  *                    Scroll to the correct position.  lDelta is the
  152.  *                    amount to CHANGE the current scroll setting by.
  153.  *
  154.  ************************************************************************/
  155. static void
  156. DoScroll (lDelta)
  157. int        lDelta;
  158. {
  159. int    newLine;
  160.  
  161.     newLine = curLine + lDelta;
  162.     if (newLine < 0) newLine = 0;
  163.     if (newLine > GetCtlMax (theScroll)) newLine = GetCtlMax (theScroll);
  164.     SetCtlValue (theScroll, newLine);
  165.     lDelta = (curLine - newLine ) * (**teHand).lineHeight;
  166.     TEScroll (0, lDelta, teHand);
  167.     curLine = newLine;
  168. }
  169.  
  170.  
  171.  
  172. /************************************************************************
  173.  *
  174.  *  Function:        __TrackScroll
  175.  *
  176.  *  Purpose:        track the scrolling
  177.  *
  178.  *  Returns:        nothing
  179.  *
  180.  *  Side Effects:    scrolling
  181.  *
  182.  *  Description:    get the control part that we're in.  If we're still
  183.  *                    in the same part, we're going to scroll.  Check what
  184.  *                    kind of part we're in, and set our delta accordingly.
  185.  *                    Call DoScroll to actually handle the scrolling.
  186.  *
  187.  ************************************************************************/
  188. static pascal void __TrackScroll (theScroll, partCode)
  189. ControlHandle    theScroll;
  190. int                partCode;
  191. {
  192. int    lDelta;
  193.  
  194.     if (partCode == GetCRefCon (theScroll))    /* still in same part? */
  195.     {
  196.         switch (partCode)
  197.         {
  198.             case inUpButton: lDelta = -1; break;
  199.             case inDownButton: lDelta = 1; break;
  200.             case inPageUp: lDelta = -halfPage; break;
  201.             case inPageDown: lDelta = halfPage; break;
  202.         }
  203.         DoScroll (lDelta);
  204.     }
  205. }
  206.  
  207.  
  208. /************************************************************************
  209.  *
  210.  *  Function:        TextFilter
  211.  *
  212.  *  Purpose:        filter to handle hits in scroll bar
  213.  *
  214.  *  Returns:        false (indicating we should continue within our
  215.  *                    modal dialog)
  216.  *
  217.  *  Side Effects:    May scroll the text
  218.  *
  219.  *  Description:    We're being called as part of a ModalDialog call.
  220.  *                    Check what kind of event activated us.  If it was a
  221.  *                    mouseDown, handle it.  If we were in the thumb, track
  222.  *                    the thumb, otherwise scroll the indicated amount.
  223.  *
  224.  ************************************************************************/
  225. static pascal Boolean TextFilter (theDialog, theEvent, itemHit)
  226. DialogPtr    theDialog;
  227. EventRecord    *theEvent;
  228. int            *itemHit;
  229. {
  230. Point    thePoint;
  231. int        thePart;
  232. Boolean    result;
  233.  
  234.     result = false;
  235.     switch (theEvent->what)
  236.     {
  237.         case mouseDown:
  238.             thePoint = theEvent->where;
  239.             GlobalToLocal (&thePoint);
  240.             thePart = TestControl (theScroll, thePoint);
  241.             if (thePart == inThumb)
  242.             {
  243.                 (void) TrackControl (theScroll, thePoint, nil);
  244.                 DoScroll (GetCtlValue (theScroll) - curLine);
  245.             }
  246.             else if (thePart != 0)
  247.             {
  248.                 SetCRefCon (theScroll, (long) thePart);
  249.                 (void) TrackControl (theScroll, thePoint, (ProcPtr)__TrackScroll);
  250.             }
  251.             break;
  252.         case keyDown:
  253.             if ((theEvent->message & charCodeMask) == ETX)
  254.             {
  255.                 *itemHit = 1;
  256.                 result = true;
  257.             }
  258.             if ((theEvent->message & charCodeMask) == CR)
  259.             {
  260.                 *itemHit = 1;
  261.                 result = true;
  262.             }
  263.             break;
  264.         case updateEvt:
  265.         case activateEvt:
  266.             HighLightDefault(theDialog);
  267.             break;
  268.     }
  269.     return (result);
  270. }
  271.  
  272.  
  273.  
  274. /************************************************************************
  275.  *
  276.  *  Function:        TextDialog
  277.  *
  278.  *  Purpose:        put up text dialog with optional scroll bar
  279.  *
  280.  *  Returns:        nothing
  281.  *
  282.  *  Side Effects:    none
  283.  *
  284.  *  Description:    Pass in a dialog number, a handle to the text to
  285.  *                    display, a font number, font size, and a boolean
  286.  *                    indicating whether you want the text to wrap or not.
  287.  *
  288.  *                    The dialog referenced by dlogNum should have the 
  289.  *                    OK button as the first item, and user items for the
  290.  *                    second and third items.  The second is the rect in
  291.  *                    which the control is drawn, the third is the rect in
  292.  *                    which text is drawn. Only the OK button should be
  293.  *                    enabled.
  294.  *
  295.  *                    The text handle should be locked before calling us,
  296.  *                    and unlocked afterwards.
  297.  *
  298.  *                    Of course, the font number and size should exist in
  299.  *                    the current system, or it will default to something
  300.  *                    ugly.
  301.  *
  302.  ************************************************************************/
  303. void
  304. TextDialog (dlogNum, textHandle, fontNum, fontSize, wrap)
  305. int        dlogNum;
  306. Handle    textHandle;
  307. int        fontNum;
  308. int        fontSize;
  309. Boolean    wrap;
  310. {
  311. GrafPtr        oldPort;
  312. DialogPtr    theDialog;
  313. int            itemNo;
  314. short        itemType;
  315. Handle        itemHandle;
  316. Rect        r;
  317. int            scrollLines;
  318. int            viewLines;
  319. Handle        oldHText;
  320. ProcPtr        filterProc = nil;
  321.  
  322.     GetPort (&oldPort);
  323.     theDialog = GetNewDialog (DU_CenterDLOG(dlogNum), (DialogPeek)nil, (WindowPtr)-1L);
  324.  
  325.     GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
  326.     SetDItem (theDialog, textRectUser, itemType, (Handle)DrawTextRect, &r);
  327. /*
  328.     incorporate text into a TERec.
  329. */
  330.     SetPort (theDialog);
  331.     TextFont (fontNum);
  332.     TextSize (fontSize);
  333.  
  334.     InsetRect (&r, 4, 4);
  335.     teHand = TENew (&r, &r);
  336.     if (!wrap)
  337.         (**teHand).crOnly = -1;
  338.     oldHText = (**teHand).hText;        /* save this.  restore later */
  339.     (**teHand).hText = textHandle;
  340.     TECalText (teHand);
  341.     viewLines = (r.bottom - r.top) / (**teHand).lineHeight;
  342.     scrollLines = (**teHand).nLines - viewLines;
  343.     needScroll = (scrollLines > 0);
  344.     GetDItem (theDialog, scrollBarUser, &itemType, &itemHandle, &r);
  345.     SetDItem (theDialog, scrollBarUser, itemType, (Handle)DrawScroll, &r);
  346.     if (needScroll)
  347.     {
  348.         theScroll = NewControl (theDialog, &r, NULL, false, 0, 0, 0,
  349.                         scrollBarProc, nil);
  350.         SetCtlMax (theScroll, scrollLines);
  351.         halfPage = viewLines / 2;
  352.         curLine = 0;
  353.         filterProc = (ProcPtr) TextFilter;
  354.     }
  355.  
  356.     ShowWindow (theDialog);
  357.  
  358.     do {
  359.         ModalDialog (filterProc, &itemNo);
  360.     } while (itemNo != OKButton);
  361.  
  362. /*
  363.     restore hText field of TE record before disposing of it.
  364. */
  365.     (**teHand).hText = oldHText;
  366.     TEDispose (teHand);
  367.  
  368.     if (needScroll)
  369.         DisposeControl (theScroll);
  370.     SetPort (oldPort);
  371.     DisposDialog(theDialog);
  372. }
  373.